package com.codepilot.server.config;

import com.codepilot.server.utils.MyPasswordEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.codepilot.server.filter.JwtAuthenticationFilter;

/**
 * Spring Security配置类
 */
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    // @Autowired
    // private AuthenticationEntryPoint authenticationEntryPoint;

    // @Autowired
    // private AccessDeniedHandler accessDeniedHandler;

    /**
     * 使用BCryptPasswordEncoder替换默认的NoOpPasswordEncoder
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
//        return new BCryptPasswordEncoder();
        return new MyPasswordEncoder();
    }

    /**
     * 在容器中注入AuthenticationManager实例
     * 
     * @throws Exception
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }

    /**
     * 配置与认证和授权有关的规则
     * 
     * @throws Exception
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                // 对于前后端分离项目，需要关闭csrf，同时设置session为无状态
                .csrf(csrf -> csrf.disable())
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                // 设置认证和授权规则（基于配置的方式）
                .authorizeHttpRequests(auth -> {
                    auth.antMatchers("/api/user/authenticate/**").permitAll();
                    auth.antMatchers("/api/user/forget").permitAll();
                    auth.antMatchers("/api/user/check-captcha").permitAll();
                    auth.antMatchers("/api/user/passwd").permitAll();
                    auth.antMatchers("/api/user/**").authenticated();
                    auth.antMatchers("/api/record/**").authenticated();
                    auth.antMatchers("/api/favor/**").authenticated();
                    auth.antMatchers("/api/problem/**").authenticated();
                    auth.antMatchers("/api/recommend/**").authenticated();
                })
                // 添加自定义的jwt认证过滤器
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
                // 设置认证和授权异常处理器
                // .exceptionHandling(handler -> {
                //     handler.authenticationEntryPoint(authenticationEntryPoint);
                //     handler.accessDeniedHandler(accessDeniedHandler);
                // })
                // 允许跨域
                .cors();
        return http.build();
    }

}
